package com.shy.springframework.beans.factory.support;

import com.shy.springframework.beans.BeansException;
import com.shy.springframework.beans.factory.FactoryBean;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 *  FactoryBean注册服务
 */
public class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry{
    // Singleton类型的FactoryBean容器
    private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>();

    protected Object getCacheObjectForFactoryBean(String beanName){
        Object object = factoryBeanObjectCache.get(beanName);
        return object != NULL_OBJECT ? object : null;
    }

    protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName){
        // Singleton类型先从内存中获取
        if (factory.isSingleton()){
            Object object = this.factoryBeanObjectCache.get(beanName);
            if (object == null){
                object = doGetObjectFromFactoryBean(factory, beanName);
                this.factoryBeanObjectCache.put(beanName, object != null ? object : NULL_OBJECT);
            }
            return object != NULL_OBJECT ? object : null;
        }else {
            return doGetObjectFromFactoryBean(factory, beanName);
        }
    }

    /**
     * 自定义Bean生成
     * @param factory
     * @param beanName
     * @return
     */
    private Object doGetObjectFromFactoryBean(final FactoryBean factory, final String beanName){
        try {
            return factory.getObject();
        } catch (Exception e) {
            throw new BeansException("FactoryBean threw exception on Object [" + beanName + "]", e);
        }
    }
}
